/**
 * @author zhangxiaofei [<1326336909@qq.com>]
 * @dateTime 2023-02-08
 *
 * 全局请求封装
 */
"use strict";

import qs from 'qs'
import axios from 'axios'
import merge from 'lodash/merge'
import { isEmpty } from '@/utils/validate'
import { useStore } from "@/hooks/store/useStore"
import { ElMessage as Message } from 'element-plus'

const install = (app, { router, opt }) => {

  const { base } = useStore();

  /**
   * 初始化
   */
  const http = axios.create({
    timeout: 1000 * 30,
    withCredentials: true,
    headers: {
      'Content-Type': 'application/json; charset=utf-8',
      'cx-auth-token': process.env.VITE_CX_AUTH_TOKEN,
    },
  })

  /**
   * 请求拦截
   */
  http.interceptors.request.use(
    (config) => {
      // 获取token
      const token = base.token

      if (!isEmpty(token)) {
        config.headers['Authorization'] = 'Bearer ' + token // 如果token 存在则携带token访问
      }

      return config
    },
    (error) => {
      return Promise.reject(error)
    }
  )

  /**
   * 响应拦截
   */
  http.interceptors.response.use(
    (response) => {

      if (response.status != 200) {
        Message.error('请求异常')
        console.log('1.错误信息: ' + response.statusText)
      } else {

        // 如果出现小于0, 代表token 失效
        if (response.data.status < 0) {
          // 清除登录数据
          base.clearData()

          // 跳转到登录页
          router.push({ name: 'login' })
        }

        // 1001 代表接口无权限或失效；1006 代表请求太频繁
        if (response.data.status == 1001 || response.data.status == 1006) {
          Message.error(response.data.message)
        }

        // 刷新了token 则重新存放
        if (!isEmpty(response.headers.authorization)) {
          var token = response.headers.authorization.split(' ')[1]

          base.setToken(token)
        }
      }

      return response
    },
    (error) => {
      // 如果地址无法请求
      if (isEmpty(error.response)) {
        Message.error('网络异常，请检查')
        console.log(error.response)
      } else {

        // 存在状态码
        if (error.response.status) {
          switch (error.response.status) {
            case 400:
              Message.error("请求错误")
              break;
            case 401:
              Message.error("请求未授权")
              router.replace({ name: 'login' })
              break;
            case 403:
              Message.error("没有权限，拒绝访问")
              break;
            case 404:
              Message.error("请求地址出错")
              router.push({ name: '404' })
              break;
            case 408:
              Message.error("请求超时")
              break;
            case 500:
              Message.error("服务器内部错误")
              router.push({ name: '500' })
              break;
            case 501:
              Message.error("服务未实现")
              break;
            case 502:
              Message.error("网关错误")
              break;
            case 503:
              Message.error("服务不可用")
              break;
            case 504:
              Message.error("网关超时")
              break;
            case 505:
              Message.error("HTTP版本不受支持")
              break;
            default:
              Message.error(error.response.statusText)
              break
          }
        }
      }

      return Promise.reject(error)
    }
  )

  /**
   * 请求地址处理
   * @param {*} actionName action方法名称
   */
  http.adornUrl = (actionName) => {
    // 非生产环境 && 开启代理, 接口前缀统一使用[/proxyApi/]前缀做代理拦截!
    return '/api' + actionName
  }

  /**
   * get请求参数处理
   * @param {*} params 参数对象
   * @param {*} openDefultParams 是否开启默认参数?
   */
  http.adornParams = (params = {}, openDefultParams = true) => {
    var defaults = {t: new Date().getTime()}
    return openDefultParams ? merge(defaults, params) : params
  }

  /**
   * post请求数据处理
   * @param {*} data 数据对象
   * @param {*} openDefultdata 是否开启默认数据?
   * @param {*} contentType 数据格式
   *            json: 'application/json; charset=utf-8'
   *            form: 'application/x-www-form-urlencoded; charset=utf-8'
   */
  http.adornData = (data = {}, openDefultdata = true, contentType = 'json') => {
    var defaults = {t: new Date().getTime()}
    data = openDefultdata ? merge(defaults, data) : data
    return contentType === 'json' ? JSON.stringify(data) : qs.stringify(data)
  }

  window[opt] = http;

  app.config.globalProperties[opt] = http;
};

export default { install };
